package summerprojectFX.utilities;

import java.util.ArrayList;
import java.util.StringTokenizer;

public class NashvilleNumbers {
	int row;
	private String song, key;
	private char[] keys = { 'B', 'C', 'D', 'E', 'F', 'G', 'b', 'c', 'd', 'e',
			'f', 'g' };
	private String[] types = { "major", "minor", "maj", "min", "add9", "sus4",
			"maj7", "m", "#", "b", "7", "sus2", "sus4", "add2", "add9", "add4",
			"madd2", "madd9", "madd4", "add2add4", "madd2add4", "aug", "dim",
			"dim7", "5", "6", "m6", "6/9", "m6/9", "6/7", "m6/7", "maj6/7",
			"m7", "maj7", "7sus4", "7sus2", "7add4", "m7add4", "9", "m9",
			"maj9", "9sus4", "11", "m11", "maj11", "13", "m13", "maj13",
			"13sus4", "mmaj7", "mmaj9", "7#9", "7b9", "7#5", "7b5", "m7#5",
			"m7b5", "maj7#5", "maj7b5", "9#5", "9b5", "/" };
	String[] sharpkeys = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F",
			"F#", "G", "G#", "A", "A#", "B", "C", "C#", "D", "D#", "E", "F",
			"F#", "G", "G#" };
	String[] flatkeys = { "Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F",
			"Gb", "G", "Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F",
			"Gb", "G" };
	String[][] allKeys = {
			{ "Ab", "Bb", "C", "Db", "Eb", "F", "G", "Ab", "Bb", "C", "Db",
					"Eb", "F", "G" }, // Ab MAJOR
			{ "A", "B", "C#", "D", "E", "F#", "G#", "A", "B", "C#", "D", "E",
					"F#", "G#" }, // A MAJOR
			{ "Bb", "C", "D", "Eb", "F", "G", "A", "Bb", "C", "D", "Eb", "F",
					"G", "A" }, // Bb MAJOR
			{ "B", "C#", "D#", "E", "F#", "G#", "A#", "B", "C#", "D#", "E",
					"F#", "G#", "A#" }, // B MAJOR
			{ "C", "D", "E", "F", "G", "A", "B", "C", "D", "E", "F", "G", "A",
					"B" }, // C MAJOR
			{ "C#", "D#", "E#", "F#", "G#", "A#", "B#", "C#", "D#", "E#", "F#",
					"G#", "A#", "B#" },// C# MAJOR
			{ "Db", "Eb", "F", "Gb", "Ab", "Bb", "C", "Db", "Eb", "F", "Gb",
					"Ab", "Bb", "C" }, // Db MAJOR
			{ "D", "E", "F#", "G", "A", "B", "C#", "D", "E", "F#", "G", "A",
					"B", "C#" }, // D MAJOR
			{ "Eb", "F", "G", "Ab", "Bb", "C", "D", "Eb", "F", "G", "Ab", "Bb",
					"C", "D" }, // Eb MAJOR
			{ "E", "F#", "G#", "A", "B", "C#", "D#", "E", "F#", "G#", "A", "B",
					"C#", "D#" }, // E MAJOR
			{ "F", "G", "A", "Bb", "C", "D", "E", "F", "G", "A", "Bb", "C",
					"D", "E" }, // F MAJOR
			{ "F#", "G#", "A#", "B", "C#", "D#", "E#", "F#", "G#", "A#", "B",
					"C#", "D#", "E#" }, // F# MAJOR
			{ "Gb", "Ab", "Bb", "Cb", "Db", "Eb", "F", "Gb", "Ab", "Bb", "Cb",
					"Db", "Eb", "F" }, // Gb MAJOR
			{ "G", "A", "B", "C", "D", "E", "F#", "G", "A", "B", "C", "D", "E",
					"F#" }, // G MAJOR
			{ "Ab", "Bb", "Cb", "Db", "Eb", "Fb", "Gb", "Ab", "Bb", "Cb", "Db",
					"Eb", "Fb", "Gb" }, // Ab Minor
			{ "A", "B", "C", "D", "E", "F", "G", "A", "B", "C", "D", "E", "F",
					"G" }, // A Minor
			{ "A#", "B#", "C#", "D#", "E#", "F#", "G#", "A#", "B#", "C#", "D#",
					"E#", "F#", "G#" }, // A# Minor
			{ "Bb", "C", "Db", "Eb", "F", "Gb", "Ab", "Bb", "C", "Db", "Eb",
					"F", "Gb", "Ab" }, // Bb Minor
			{ "B", "C#", "D", "E", "F#", "G", "A", "B", "C#", "D", "E", "F#",
					"G", "A" }, // B Minor
			{ "C", "D", "Eb", "F", "G", "Ab", "Bb", "C", "D", "Eb", "F", "G",
					"Ab", "Bb" }, // C Minor
			{ "C#", "D#", "E", "F#", "G#", "A", "B", "C#", "D#", "E", "F#",
					"G#", "A", "B" }, // C# Minor
			{ "D", "E", "F", "G", "A", "Bb", "C", "D", "E", "F", "G", "A",
					"Bb", "C" }, // D Minor
			{ "D#", "E#", "F#", "G#", "A#", "B", "C#", "D#", "E#", "F#", "G#",
					"A#", "B", "C#" }, // D# Minor
			{ "Eb", "F", "Gb", "Ab", "Bb", "Cb", "Db", "Eb", "F", "Gb", "Ab",
					"Bb", "Cb", "Db" }, // Eb Minor
			{ "E", "F#", "G", "A", "B", "C", "D", "E", "F#", "G", "A", "B",
					"C", "D" }, // E Minor
			{ "F", "G", "Ab", "Bb", "C", "Db", "Eb", "F", "G", "Ab", "Bb", "C",
					"Db", "Eb" }, // F Minor
			{ "F#", "G#", "A", "B", "C#", "D", "E", "F#", "G#", "A", "B", "C#",
					"D", "E" }, // F# Minor
			{ "G", "A", "Bb", "C", "D", "Eb", "F", "G", "A", "Bb", "C", "D",
					"Eb", "F" }, // G Minor
			{ "G#", "A#", "B", "C#", "D#", "E", "F#", "G#", "A#", "B", "C#",
					"D#", "E", "F#" }, // G# Minor

	};

	public NashvilleNumbers(String mySong, String myKey) {
		song = mySong;
		key = myKey;

		switch (key) {
		case "Ab Major":
			row = 0;
			break;
		case "A Major":
			row = 1;
			break;
		case "Bb Major":
			row = 2;
			break;
		case "B Major":
			row = 3;
			break;
		case "C Major":
			row = 4;
			break;
		case "C# Major":
			row = 5;
			break;
		case "Db Major":
			row = 6;
			break;
		case "D Major":
			row = 7;
			break;
		case "Eb Major":
			row = 8;
			break;
		case "E Major":
			row = 9;
			break;
		case "F Major":
			row = 10;
			break;
		case "F# Major":
			row = 11;
			break;
		case "Gb Major":
			row = 12;
			break;
		case "G Major":
			row = 13;
			break;
		case "Ab Minor":
			row = 14;
			break;
		case "A Minor":
			row = 15;
			break;
		case "A# Minor":
			row = 16;
			break;
		case "Bb Minor":
			row = 17;
			break;
		case "B Minor":
			row = 18;
			break;
		case "C Minor":
			row = 19;
			break;
		case "C# Minor":
			row = 20;
			break;
		case "D Minor":
			row = 21;
			break;
		case "D# Minor":
			row = 22;
			break;
		case "Eb Minor":
			row = 23;
			break;
		case "E Minor":
			row = 24;
			break;
		case "F Minor":
			row = 25;
			break;
		case "F# Minor":
			row = 26;
			break;
		case "G Minor":
			row = 27;
			break;
		case "G# Minor":
			row = 28;
			break;
		default:
			row = 0;
			break;
		}
	}

	public String convert() {
		String newSong = "";
		String[] holder = song.split("\\n+");
		ArrayList<String> oneLine;

		for (String s : holder) {
			oneLine = new ArrayList<String>();
			StringTokenizer st = new StringTokenizer(s, "\t ", true);
			while (st.hasMoreTokens()) {
				oneLine.add(st.nextToken());
			}

			  StringTokenizer st1 = new StringTokenizer(s, " \t", false); 
			ArrayList<String> temp = new ArrayList();
                        
			while(st1.hasMoreTokens()){
                            
                                                            temp.add(st1.nextToken());
                                                            
                                                        }
                                                    
                                                        String[] noWhiteSpace = temp.toArray(new String[temp.size()]);

			if ((noWhiteSpace.length == 1 && (s.charAt(0) == 'A' || s.charAt(0) == 'a'))
					|| isChordLine(noWhiteSpace) == true) {
				s = numberChange(oneLine);
			}
			newSong += s + "\n";
		}
		return newSong;
	}

	private String numberChange(ArrayList<String> oneLine) {
		String rValue = "";
		for (int i = 0; i < oneLine.size(); i++) {
			String temp = oneLine.get(i);
			if (Character.isLetter(temp.charAt(0))) {
				rValue += move(temp);
			} else {
				rValue += temp;
			}
		}
		return rValue;
	}

	private String move(String temp) {
		String returnValue = "";
		String root = "";
		if (temp.length() == 1) {
			root = temp;
		} else if (temp.charAt(1) == '#' || temp.charAt(1) == 'b') {
			root = temp.substring(0, 2);
		} else {
			root = temp.substring(0, 1);
		}
		for (int i = 0; i < 8; i++) {
			if (root.equals(allKeys[row][i])) {
				if (root.equals(allKeys[row][i])) {
					if ((temp.length() == 2 && temp.substring(1).equals("7"))
							|| (temp.length() > 2 && temp.substring(2).equals(
									"7"))) {
						returnValue = (Integer.toString(i + 1) + " -7");
						break;
					} else if (root.length() > 1) {
						returnValue = (Integer.toString(i + 1) + temp
								.substring(2));
						break;
					} else {
						returnValue = (Integer.toString(i + 1) + temp
								.substring(1));
						break;
					}
				}
			} else {
				if (root.charAt(0) == allKeys[row][i].charAt(0)) {
					if (root.length() == 1) {
						if (allKeys[row][i].charAt(1) == '#') {
							if (temp.substring(1).equals("7")) {
								returnValue = (Integer.toString(i + 1) + "b" + " -7");
							} else {
								returnValue = (Integer.toString(i + 1) + "b" + temp
										.substring(1));
							}
						} else {
							if (temp.substring(1).equals("7")) {
								returnValue = (Integer.toString(i + 1) + "#" + " -7");
							} else {
								returnValue = (Integer.toString(i + 1) + "#" + temp
										.substring(1));
							}
						}
					} else {
						if (root.charAt(1) == '#') {
							if (temp.substring(2).equals("7")) {
								returnValue = (Integer.toString(i + 1) + "#" + " -7");
							} else {
								returnValue = (Integer.toString(i + 1) + "#" + temp
										.substring(2));
							}
						} else {
							if (temp.substring(2).equals("7")) {
								returnValue = (Integer.toString(i + 1) + "b" + " -7");
							} else {
								returnValue = (Integer.toString(i + 1) + "b" + temp
										.substring(2));
							}
						}
					}
				}
			}
		}

		if (returnValue.length() > 2) {
			if (returnValue.charAt(1) == '/') {
				return returnValue.substring(0, 2)
						+ move(returnValue.substring(2));
			} else if (returnValue.charAt(2) == '/') {
				return returnValue.substring(0, 3)
						+ move(returnValue.substring(3));
			}
		}

		return returnValue;
	}

	private boolean isChordLine(String[] noWhiteSpace) {
		for (String s : noWhiteSpace) {
			if (isChord(s) == true) {
				return true;
			}
		}
		return false;
	}

	private boolean isChord(String chord) {
		for (char key : keys) {
			if (chord.length() > 0) {
				if (chord.charAt(0) == key) {
					if (chord.length() == 1) {
						return true;
					} else if (chord.length() > 1) {
						for (String type : types) {
							if (type.equalsIgnoreCase(chord.substring(1))
									|| (type.equalsIgnoreCase(chord
											.substring(2)) && (chord.charAt(1) == 'b' || chord
											.charAt(1) == '#'))) {
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}

}
